home *** CD-ROM | disk | FTP | other *** search
/ Hardcore Visual Basic 5.0 (2nd Edition) / Hardcore Visual Basic 5.0 - Second Edition (1997)(Microsoft Press).iso / Code / Winwatch.frm < prev    next >
Text File  |  1997-06-14  |  44KB  |  1,417 lines

  1. VERSION 5.00
  2. Object = "{6B7E6392-850A-101B-AFC0-4210102A8DA7}#1.1#0"; "COMCTL32.OCX"
  3. Begin VB.Form FWatch 
  4.    AutoRedraw      =   -1  'True
  5.    BorderStyle     =   1  'Fixed Single
  6.    Caption         =   "WinWatch"
  7.    ClientHeight    =   6045
  8.    ClientLeft      =   1605
  9.    ClientTop       =   2130
  10.    ClientWidth     =   9360
  11.    BeginProperty Font 
  12.       Name            =   "MS Sans Serif"
  13.       Size            =   8.25
  14.       Charset         =   0
  15.       Weight          =   700
  16.       Underline       =   0   'False
  17.       Italic          =   0   'False
  18.       Strikethrough   =   0   'False
  19.    EndProperty
  20.    Icon            =   "Winwatch.frx":0000
  21.    LinkMode        =   1  'Source
  22.    LinkTopic       =   "Form1"
  23.    MaxButton       =   0   'False
  24.    PaletteMode     =   1  'UseZOrder
  25.    ScaleHeight     =   6045
  26.    ScaleWidth      =   9360
  27.    Begin ComctlLib.TreeView tvwWin 
  28.       Height          =   1695
  29.       Left            =   4920
  30.       TabIndex        =   30
  31.       Top             =   2520
  32.       Width           =   4335
  33.       _ExtentX        =   7646
  34.       _ExtentY        =   2990
  35.       _Version        =   327680
  36.       HideSelection   =   0   'False
  37.       LabelEdit       =   1
  38.       LineStyle       =   1
  39.       Style           =   6
  40.       Appearance      =   1
  41.       MouseIcon       =   "Winwatch.frx":0CFA
  42.    End
  43.    Begin VB.ListBox lstTopWin 
  44.       Height          =   1425
  45.       Left            =   120
  46.       Sorted          =   -1  'True
  47.       TabIndex        =   29
  48.       Top             =   4530
  49.       Width           =   2175
  50.    End
  51.    Begin VB.ListBox lstResource 
  52.       Height          =   1425
  53.       Left            =   7080
  54.       Sorted          =   -1  'True
  55.       TabIndex        =   28
  56.       Top             =   4532
  57.       Width           =   2175
  58.    End
  59.    Begin VB.ListBox lstModule 
  60.       Height          =   1425
  61.       Left            =   4760
  62.       TabIndex        =   27
  63.       Top             =   4534
  64.       Width           =   2175
  65.    End
  66.    Begin VB.ListBox lstProcess 
  67.       Height          =   1425
  68.       Left            =   2440
  69.       Sorted          =   -1  'True
  70.       TabIndex        =   26
  71.       Top             =   4536
  72.       Width           =   2175
  73.    End
  74.    Begin VB.CheckBox chkBlank 
  75.       Caption         =   "Show Blank"
  76.       Height          =   255
  77.       Left            =   1200
  78.       TabIndex        =   21
  79.       Top             =   3756
  80.       Width           =   1695
  81.    End
  82.    Begin VB.CheckBox chkOwned 
  83.       Caption         =   "Show Owned"
  84.       Height          =   255
  85.       Left            =   1200
  86.       TabIndex        =   20
  87.       Top             =   3516
  88.       Width           =   1695
  89.    End
  90.    Begin VB.PictureBox bstMenu 
  91.       Height          =   480
  92.       Left            =   8445
  93.       ScaleHeight     =   420
  94.       ScaleWidth      =   1140
  95.       TabIndex        =   19
  96.       Top             =   6840
  97.       Width           =   1200
  98.    End
  99.    Begin VB.CheckBox chkFilter 
  100.       Caption         =   "Filter Resources"
  101.       Height          =   255
  102.       Left            =   3000
  103.       TabIndex        =   18
  104.       Top             =   3996
  105.       Value           =   1  'Checked
  106.       Width           =   1845
  107.    End
  108.    Begin VB.PictureBox pbDump 
  109.       AutoRedraw      =   -1  'True
  110.       Height          =   396
  111.       Left            =   165
  112.       ScaleHeight     =   330
  113.       ScaleWidth      =   495
  114.       TabIndex        =   17
  115.       Top             =   3720
  116.       Visible         =   0   'False
  117.       Width           =   552
  118.    End
  119.    Begin VB.CommandButton cmdDump 
  120.       Caption         =   "&Dump"
  121.       Height          =   372
  122.       Left            =   120
  123.       TabIndex        =   16
  124.       Top             =   2770
  125.       Width           =   972
  126.    End
  127.    Begin VB.CommandButton cmdLogFile 
  128.       Caption         =   "&Log File"
  129.       Height          =   372
  130.       Left            =   120
  131.       TabIndex        =   13
  132.       Top             =   360
  133.       Width           =   972
  134.    End
  135.    Begin VB.CheckBox chkInvisible 
  136.       Caption         =   "Show Invisible"
  137.       Height          =   255
  138.       Left            =   1200
  139.       TabIndex        =   12
  140.       Top             =   3996
  141.       Width           =   1695
  142.    End
  143.    Begin VB.CommandButton cmdSave 
  144.       Caption         =   "&Save"
  145.       Height          =   372
  146.       Left            =   120
  147.       TabIndex        =   9
  148.       Top             =   842
  149.       Width           =   972
  150.    End
  151.    Begin VB.CommandButton cmdRefresh 
  152.       Caption         =   "&Refresh"
  153.       Height          =   372
  154.       Left            =   120
  155.       TabIndex        =   5
  156.       Top             =   2288
  157.       Width           =   972
  158.    End
  159.    Begin VB.CommandButton cmdPoint 
  160.       Caption         =   "&Point"
  161.       Height          =   372
  162.       Left            =   120
  163.       TabIndex        =   1
  164.       Top             =   1324
  165.       Width           =   972
  166.    End
  167.    Begin VB.CommandButton cmdActivate 
  168.       Caption         =   "&Activate"
  169.       Height          =   372
  170.       Left            =   120
  171.       TabIndex        =   2
  172.       Top             =   1806
  173.       Width           =   972
  174.    End
  175.    Begin VB.CommandButton cmdExit 
  176.       Caption         =   "E&xit"
  177.       Height          =   372
  178.       Left            =   120
  179.       TabIndex        =   3
  180.       Top             =   3255
  181.       Width           =   972
  182.    End
  183.    Begin VB.PictureBox pbResource 
  184.       Appearance      =   0  'Flat
  185.       AutoRedraw      =   -1  'True
  186.       BackColor       =   &H80000005&
  187.       BorderStyle     =   0  'None
  188.       DragIcon        =   "Winwatch.frx":0D16
  189.       BeginProperty Font 
  190.          Name            =   "Courier New"
  191.          Size            =   7.5
  192.          Charset         =   0
  193.          Weight          =   400
  194.          Underline       =   0   'False
  195.          Italic          =   0   'False
  196.          Strikethrough   =   0   'False
  197.       EndProperty
  198.       ForeColor       =   &H80000008&
  199.       Height          =   3264
  200.       Left            =   1200
  201.       ScaleHeight     =   3270
  202.       ScaleWidth      =   3630
  203.       TabIndex        =   4
  204.       Top             =   216
  205.       Width           =   3624
  206.    End
  207.    Begin VB.Image imgCloud 
  208.       Height          =   1920
  209.       Left            =   2970
  210.       Picture         =   "Winwatch.frx":0E68
  211.       Top             =   1755
  212.       Visible         =   0   'False
  213.       Width           =   1920
  214.    End
  215.    Begin VB.Label lbl 
  216.       Caption         =   "Module:"
  217.       Height          =   228
  218.       Index           =   4
  219.       Left            =   7008
  220.       TabIndex        =   25
  221.       Top             =   1236
  222.       Width           =   1896
  223.    End
  224.    Begin VB.Label lblMod 
  225.       BeginProperty Font 
  226.          Name            =   "MS Sans Serif"
  227.          Size            =   8.25
  228.          Charset         =   0
  229.          Weight          =   400
  230.          Underline       =   0   'False
  231.          Italic          =   0   'False
  232.          Strikethrough   =   0   'False
  233.       EndProperty
  234.       Height          =   768
  235.       Left            =   6984
  236.       TabIndex        =   24
  237.       Top             =   1476
  238.       Width           =   2028
  239.    End
  240.    Begin VB.Label lblProc 
  241.       BeginProperty Font 
  242.          Name            =   "MS Sans Serif"
  243.          Size            =   8.25
  244.          Charset         =   0
  245.          Weight          =   400
  246.          Underline       =   0   'False
  247.          Italic          =   0   'False
  248.          Strikethrough   =   0   'False
  249.       EndProperty
  250.       Height          =   840
  251.       Left            =   4968
  252.       TabIndex        =   23
  253.       Top             =   1464
  254.       Width           =   2028
  255.    End
  256.    Begin VB.Label lbl 
  257.       Caption         =   "Process:"
  258.       Height          =   228
  259.       Index           =   2
  260.       Left            =   4956
  261.       TabIndex        =   22
  262.       Top             =   1224
  263.       Width           =   1896
  264.    End
  265.    Begin VB.Label lbl 
  266.       Caption         =   "Window Hierarchy:"
  267.       Height          =   228
  268.       Index           =   3
  269.       Left            =   4956
  270.       TabIndex        =   15
  271.       Top             =   2304
  272.       Width           =   2220
  273.    End
  274.    Begin VB.Label lbl 
  275.       Caption         =   "Window:"
  276.       Height          =   228
  277.       Index           =   1
  278.       Left            =   4932
  279.       TabIndex        =   14
  280.       Top             =   0
  281.       Width           =   4212
  282.    End
  283.    Begin VB.Label lblWin 
  284.       BeginProperty Font 
  285.          Name            =   "MS Sans Serif"
  286.          Size            =   8.25
  287.          Charset         =   0
  288.          Weight          =   400
  289.          Underline       =   0   'False
  290.          Italic          =   0   'False
  291.          Strikethrough   =   0   'False
  292.       EndProperty
  293.       Height          =   1044
  294.       Left            =   4944
  295.       TabIndex        =   10
  296.       Top             =   228
  297.       Width           =   4116
  298.    End
  299.    Begin VB.Label lblResource 
  300.       Caption         =   "Resources:"
  301.       Height          =   252
  302.       Left            =   7080
  303.       TabIndex        =   11
  304.       Top             =   4320
  305.       Width           =   1140
  306.    End
  307.    Begin VB.Label lblProcess 
  308.       Caption         =   "Processes:"
  309.       Height          =   255
  310.       Left            =   2440
  311.       TabIndex        =   8
  312.       Top             =   4320
  313.       Width           =   1935
  314.    End
  315.    Begin VB.Label lblModule 
  316.       Caption         =   "Modules:"
  317.       Height          =   255
  318.       Left            =   4760
  319.       TabIndex        =   7
  320.       Top             =   4320
  321.       Width           =   2175
  322.    End
  323.    Begin VB.Label lbl 
  324.       Caption         =   "Top Windows:"
  325.       Height          =   255
  326.       Index           =   0
  327.       Left            =   120
  328.       TabIndex        =   6
  329.       Top             =   4320
  330.       Width           =   2175
  331.    End
  332.    Begin VB.Label lblMsg 
  333.       Caption         =   "Resource Information:"
  334.       Height          =   255
  335.       Left            =   1200
  336.       TabIndex        =   0
  337.       Top             =   0
  338.       Width           =   3255
  339.    End
  340.    Begin VB.Menu mnuFile 
  341.       Caption         =   "&File"
  342.       Begin VB.Menu mnuLogFile 
  343.          Caption         =   "&Log File"
  344.       End
  345.       Begin VB.Menu mnuSave 
  346.          Caption         =   "&Save"
  347.       End
  348.       Begin VB.Menu mnuPoint 
  349.          Caption         =   "&Point"
  350.       End
  351.       Begin VB.Menu mnuActivate 
  352.          Caption         =   "&Activate"
  353.       End
  354.       Begin VB.Menu mnuRefresh 
  355.          Caption         =   "&Refresh"
  356.       End
  357.       Begin VB.Menu mnuDump 
  358.          Caption         =   "&Dump"
  359.       End
  360.       Begin VB.Menu mnuExit 
  361.          Caption         =   "E&xit"
  362.       End
  363.    End
  364. End
  365. Attribute VB_Name = "FWatch"
  366. Attribute VB_GlobalNameSpace = False
  367. Attribute VB_Creatable = False
  368. Attribute VB_PredeclaredId = True
  369. Attribute VB_Exposed = False
  370. Option Explicit
  371.  
  372. Private idProcCur As Long
  373. Private hModCur As Long
  374. Private hModFree As Long
  375. Private hTopWndCur As Long
  376. Private hWndCur As Long
  377. Private hInstCur As Long
  378. Private sModCur As String
  379. Private hResourceCur As Long
  380. Private hResourceLast As Long
  381. Private fCapture As Boolean
  382. Private ordResourceLast As Integer
  383. Private ordPointerLast As Integer
  384. Private dxPicMax As Long, dyPicMax As Long
  385. Private nFileCur As Integer
  386.  
  387. Const sMsg = "Resource Information:"
  388.  
  389. Public Enum EUpdateType
  390.     eutTopWindow
  391.     eutWindow
  392.     eutProcess
  393.     eutModule
  394. End Enum
  395.  
  396. ' Constants for accessing icon directory and entry structures
  397. Enum EIconDirEntryImage
  398.     ' Group Directory
  399.     wReserved = 0
  400.     wType = 2
  401.     wCount = 4
  402.     entFirst = 6
  403.         ' Icon Group Entry
  404.         bWidth = 0
  405.         bHeight = 1
  406.         bColorCount = 2
  407.         bReserved = 3
  408.         wPlanes = 4
  409.         wBitCount = 6
  410.         dwBytesInRes = 8
  411.         wID = 12
  412.         cEntrySize = 14
  413.         ' Cursor Group Entry
  414.         wWidth = 0
  415.         wHeight = 2
  416.         ' Rest same as Icon
  417. End Enum
  418.  
  419. ' Flag to prevent recursion in
  420. Private fInClick As Boolean
  421.  
  422. Private Sub Form_Load()
  423.             
  424.     Debug.Print GetFullPath("vb5.exe")
  425.         
  426.     Dim hWndOther As Long
  427.     hWndOther = GetFirstInstWnd(Me.hWnd)
  428.     If hWndOther <> hNull Then
  429.         ' Uncomment this line for debugging
  430.         'MsgBox "Activating first instance"
  431.         SetForegroundWindow hWndOther
  432.         End
  433.     End If
  434.     dxPicMax = pbResource.Width
  435.     dyPicMax = pbResource.Height
  436.     ChDrive App.Path
  437.     ChDir App.Path
  438.     PaletteMode = vbPaletteModeCustom
  439.     Palette = pbResource.Picture
  440.        
  441.     Show
  442.     RefreshAllLists
  443.  
  444. End Sub
  445.  
  446. Private Sub Form_Paint()
  447.     pbResource.Refresh
  448. End Sub
  449.  
  450. Private Sub Form_Unload(Cancel As Integer)
  451.     BugTerm
  452.     ClearResource
  453. End Sub
  454.  
  455. Private Sub RefreshAllLists(Optional hWnd As Long)
  456.     ' Prevent calling again until this one finishes
  457.     Static fInside As Integer
  458.     If fInside Then Exit Sub
  459.     fInside = True
  460.     
  461.     RefreshFullWinList False
  462.     RefreshTopWinList
  463.     RefreshProcessList
  464.     
  465.     ' Update entire display
  466.     fInClick = True
  467.     hWndCur = 0: hTopWndCur = 0: idProcCur = 0
  468.     hWnd = IIf(hWnd, hWnd, lstTopWin.ItemData(0))
  469.     UpdateDisplay eutWindow, hWnd
  470.     fInClick = False
  471.     
  472.     fInside = False
  473. End Sub
  474.  
  475. Private Sub RefreshFullWinList(fLogFile As Boolean)
  476.     Const sLog = "WINLIST.TXT"
  477.  
  478.     Call LockWindowUpdate(tvwWin.hWnd)
  479.     tvwWin.Nodes.Clear
  480.     HourGlass Me
  481.     If fLogFile Then
  482.         lblMsg.Caption = "Creating log file " & sLog & "..."
  483.         nFileCur = FreeFile
  484.         Open sLog For Output As nFileCur
  485.         Print #nFileCur, sEmpty
  486.         Print #nFileCur, "Window List " & sCrLf
  487.         Dim helperFile As CWindowToFile
  488.         Set helperFile = New CWindowToFile
  489.         helperFile.FileNumber = nFileCur
  490.         Call IterateChildWindows(-1, GetDesktopWindow(), helperFile)
  491.         Close nFileCur
  492.     Else
  493.         lblMsg.Caption = "Building window list..."
  494.         Dim helperForm As CWindowToForm
  495.         Set helperForm = New CWindowToForm
  496.         Set helperForm.TreeViewControl = tvwWin
  497.         helperForm.ShowInvisible = chkInvisible
  498.         Call IterateChildWindows(-1, GetDesktopWindow(), helperForm)
  499.     End If
  500.     lblMsg.Caption = sMsg
  501.     HourGlass Me
  502.     tvwWin.Refresh
  503.     Call LockWindowUpdate(hNull)
  504. End Sub
  505.  
  506. Private Sub RefreshTopWinList()
  507.     Dim sTitle As String, hWnd As Long
  508.     
  509.     SetRedraw lstTopWin, False
  510.     lstTopWin.Clear
  511.     ' Get first top-level window
  512.     hWnd = GetWindow(GetDesktopWindow(), GW_CHILD)
  513.     BugAssert hWnd <> hNull
  514.     ' Iterate through remaining windows
  515.     Do While hWnd <> hNull
  516.         sTitle = WindowTextLineFromWnd(hWnd)
  517.         ' Determine whether to display titled, visible, and unowned
  518.         If IsVisibleTopWnd(hWnd, chkBlank, _
  519.                            chkInvisible, chkOwned) Then
  520.             lstTopWin.AddItem sTitle
  521.             lstTopWin.ItemData(lstTopWin.NewIndex) = hWnd
  522.         End If
  523.         ' Get next child
  524.         hWnd = GetWindow(hWnd, GW_HWNDNEXT)
  525.     Loop
  526.     SetRedraw lstTopWin, True
  527. End Sub
  528.  
  529. Private Sub RefreshProcessList()
  530.     Dim processes As CVector, process As CProcess, i As Long
  531.     Set processes = CreateProcessList
  532.     SetRedraw lstProcess, False
  533.     lstProcess.Clear
  534.     For i = 1 To processes.Last
  535.         lstProcess.AddItem processes(i).EXEName
  536.         lstProcess.ItemData(lstProcess.NewIndex) = processes(i).id
  537.     Next
  538.     SetRedraw lstProcess, True
  539. End Sub
  540.  
  541. Private Sub RefreshModuleList(idProc As Long)
  542.     Dim modules As CVector, module As CModule, i As Long
  543.     Set modules = CreateModuleList(idProc)
  544.     
  545.     ' Illustrate three ways to prevent visible window update
  546. #Const ordQuiet = 0
  547. #If ordQuiet = 0 Then
  548.     SetRedraw lstModule, False
  549. #ElseIf ordQuiet = 1 Then
  550.     Call LockWindowUpdate(lstModule.hWnd)
  551. #ElseIf ordQuiet = 2 Then
  552.     lstModule.Visible = False
  553. #End If
  554.     lstModule.Clear
  555.  
  556.     ' Add module names and handles
  557.     For i = 1 To modules.Last
  558.         lstModule.AddItem modules(i).ExeFile
  559.         lstModule.ItemData(lstModule.NewIndex) = modules(i).Handle
  560.     Next
  561.     ' Look up main executable file
  562.     lstModule.ListIndex = LookupItem(lstModule, ExeNameFromProcID(idProc))
  563.     If lstModule.ListIndex = -1 Then lstModule.ListIndex = 0
  564.     
  565. #If ordQuiet = 0 Then
  566.     SetRedraw lstModule, True
  567. #ElseIf ordQuiet = 1 Then
  568.     Call LockWindowUpdate(hNull)
  569. #ElseIf ordQuiet = 2 Then
  570.     lstModule.Visible = True
  571. #End If
  572.  
  573. End Sub
  574.  
  575. Private Sub lstTopWin_DblClick()
  576. #Const fWindowsWay = 0
  577. #If fWindowsWay Then
  578.     SetForegroundWindow hTopWndCur
  579. #Else
  580.     ' Ignore errors
  581.     On Error Resume Next
  582.     AppActivate lstTopWin.Text
  583.     If Err Then BugMessage "AppActivate error: " & Err
  584. #End If
  585. End Sub
  586.  
  587. Private Sub lstTopWin_Click()
  588.  
  589.     ' Module-level flag to prevent circular references
  590.     If fInClick Then Exit Sub
  591.     fInClick = True
  592.     
  593.     ' Look up window handle
  594.     Dim hWnd As Long
  595.     hWnd = lstTopWin.ItemData(lstTopWin.ListIndex)
  596.     UpdateDisplay eutTopWindow, hWnd
  597.     
  598.     fInClick = False
  599. End Sub
  600.  
  601. Private Sub lstProcess_Click()
  602.  
  603.     ' Module-level flag to prevent circular references
  604.     If fInClick Then Exit Sub
  605.     fInClick = True
  606.  
  607.     ' Load process ID
  608.     Dim idProc As Long
  609.     idProc = lstProcess.ItemData(lstProcess.ListIndex)
  610.     UpdateDisplay eutProcess, idProc
  611.         
  612.     fInClick = False
  613. End Sub
  614.  
  615. Private Sub lstModule_Click()
  616.  
  617.     ' Module-level flag to prevent circular references
  618.     If fInClick Then Exit Sub
  619.     fInClick = True
  620.     
  621.     UpdateDisplay eutModule, lstModule.ItemData(lstModule.ListIndex)
  622.     
  623.     fInClick = False
  624. End Sub
  625.  
  626. Private Sub chkFilter_Click()
  627.     UpdateResources hModCur
  628. End Sub
  629.  
  630. Private Sub chkInvisible_Click()
  631.     RefreshAllLists
  632. End Sub
  633.  
  634. Private Sub chkOwned_Click()
  635.     RefreshAllLists
  636. End Sub
  637.  
  638. Private Sub chkBlank_Click()
  639.     RefreshAllLists
  640. End Sub
  641.  
  642. Private Sub cmdActivate_Click()
  643.     SetForegroundWindow hWndCur
  644. End Sub
  645.  
  646. Private Sub cmdDump_Click()
  647.     Dim hDCCur As Long, hWndOld As Long
  648.     Dim tim As Double
  649.     Dim RECT As RECT, dx As Long, dy As Long
  650.     
  651.     ' Save current window, and switch to capture window
  652.     hWndOld = GetActiveWindow()
  653.     SetForegroundWindow hWndCur
  654.     ' Give window time to repaint
  655.     tim = Timer + 0.5
  656.     Do
  657.         DoEvents
  658.     Loop Until Timer >= tim
  659.     ' Borrow window DC
  660.     hDCCur = GetWindowDC(hWndCur)
  661.     Call GetWindowRect(hWndCur, RECT)
  662.     dx = RECT.Right - RECT.Left + 2: dy = RECT.bottom - RECT.Top + 2
  663.     ' Blit window DC to hidden picture box
  664.     With pbDump
  665.         .Width = Screen.TwipsPerPixelX * dx
  666.         .Height = Screen.TwipsPerPixelY * dy
  667.         Call BitBlt(.hDC, 0, 0, dx, dy, hDCCur, 0, 0, vbSrcCopy)
  668.         ' Copy from DC to Picture
  669.         .Picture = .Image
  670.     End With
  671.     ' Give DC back
  672.     Call ReleaseDC(hWndCur, hDCCur)
  673.     SetForegroundWindow hWndOld
  674.     ' Save Picture property in file
  675.     Dim sFile As String, sDirCur As String
  676.     sDirCur = CurDir
  677.     If VBGetSaveFileName(filename:="*.BMP", _
  678.                          FileTitle:=sFile, _
  679.                          InitDir:=sDirCur, _
  680.                          DlgTitle:="Save Window As", _
  681.                          Filter:="Bitmaps (*.BMP) | *.BMP)", _
  682.                          DefaultExt:="BMP") Then
  683.             SavePicture pbDump.Picture, sFile
  684.     End If
  685.     ChDir sDirCur
  686. End Sub
  687.  
  688. Private Sub cmdExit_Click()
  689.     Unload Me
  690. End Sub
  691.  
  692. Private Sub cmdLogFile_Click()
  693.     RefreshFullWinList True
  694. End Sub
  695.  
  696. Private Sub cmdPoint_Click()
  697.     If cmdPoint.Caption = "&Point" Then
  698.         fCapture = True
  699.         cmdPoint.Caption = "End &Point"
  700.         Call SetCapture(Me.hWnd)
  701.         lblMsg.Caption = "Move mouse for window information"
  702.     Else
  703.         fCapture = False
  704.         cmdPoint.Caption = "&Point"
  705.         ReleaseCapture
  706.         lblMsg.Caption = sMsg
  707.     End If
  708. End Sub
  709.  
  710. Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
  711.                            X As Single, Y As Single)
  712.     If fCapture Then
  713.         Dim pt As POINTL
  714.         Dim hWnd As Long
  715.         Dim idProc As Long
  716.         pt.X = X / Screen.TwipsPerPixelX
  717.         pt.Y = Y / Screen.TwipsPerPixelY
  718.         ClientToScreen Me.hWnd, pt
  719.         hWnd = WindowFromPoint(pt.X, pt.Y)
  720.         If hWnd <> hNull Then
  721.             ' Turn point mode off
  722.             fCapture = False
  723.             cmdPoint.Caption = "&Point"
  724.             On Error Resume Next
  725.             Dim nodX As Node
  726.             Set nodX = tvwWin.Nodes.Item("W" & hWnd)
  727.             ' If window isn't in list, refresh the display
  728.             fInClick = True
  729.             If nodX Is Nothing Then
  730.                 RefreshAllLists hWnd
  731.             Else
  732.                 UpdateDisplay eutWindow, hWnd
  733.                 lblMsg.Caption = sMsg
  734.             End If
  735.             fInClick = False
  736.         End If
  737.     End If
  738. End Sub
  739.  
  740. Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
  741.                            X As Single, Y As Single)
  742.     If fCapture Then
  743.         Dim pt As POINTL, hWnd As Long
  744.         Static hWndLast As Long
  745.         ' Set point and convert it to screen coordinates
  746.         pt.X = X / Screen.TwipsPerPixelX
  747.         pt.Y = Y / Screen.TwipsPerPixelY
  748.         ClientToScreen Me.hWnd, pt
  749.         ' Find window under it
  750.         hWnd = WindowFromPoint(pt.X, pt.Y)
  751.         ' Update display only if window has changed
  752.         If hWnd <> hWndLast Then
  753.             lblWin.Caption = GetWndInfo(hWnd)
  754.             hWndLast = hWnd
  755.         End If
  756.     End If
  757. End Sub
  758.  
  759. Private Sub cmdRefresh_Click()
  760.     ' Maintain currently selected item
  761.     RefreshAllLists lstTopWin.ItemData(lstTopWin.ListIndex)
  762. End Sub
  763.  
  764. Private Sub cmdSave_Click()
  765.     Dim sDirCur As String, sFileTitle As String, sFile As String
  766.     Dim sDlgTitle As String, sFilter As String, sDefaultExt As String
  767.     sDirCur = CurDir$
  768.  
  769.     Select Case ordResourceLast
  770.     Case RT_BITMAP
  771.         sFile = "*.BMP"
  772.         sDlgTitle = "Save Bitmap As"
  773.         sFilter = "Bitmaps (*.BMP) | *.BMP)"
  774.         sDefaultExt = "BMP"
  775.                    
  776.     Case RT_ICON, RT_GROUP_ICON
  777.         sFile = "*.ICO"
  778.         sDlgTitle = "Save Icon As"
  779.         sFilter = "Icons (*.ICO) | *.ICO)"
  780.         sDefaultExt = "ICO"
  781.         
  782.     Case RT_CURSOR, RT_GROUP_CURSOR
  783.         sFile = "*.CUR"
  784.         sDlgTitle = "Save Cursor As"
  785.         sFilter = "Cursors (*.CUR) | *.CUR)"
  786.         sDefaultExt = "CUR"
  787.     
  788.     Case Else
  789.         Exit Sub
  790.     End Select
  791.     If VBGetSaveFileName(filename:=sFile, _
  792.                          FileTitle:=sFileTitle, _
  793.                          InitDir:=sDirCur, _
  794.                          DlgTitle:=sDlgTitle, _
  795.                          Filter:=sFilter, _
  796.                          DefaultExt:=sDefaultExt) Then
  797.         If ordResourceLast <> RT_CURSOR And ordResourceLast <> RT_GROUP_CURSOR Then
  798.             SavePicture pbResource.Picture, sFileTitle
  799.         End If
  800.     End If
  801.     ChDir sDirCur
  802. End Sub
  803.  
  804. Private Sub mnuActivate_Click()
  805.     cmdActivate_Click
  806. End Sub
  807.  
  808. Private Sub mnuDump_Click()
  809.     cmdDump_Click
  810. End Sub
  811.  
  812. Private Sub mnuExit_Click()
  813.     cmdExit_Click
  814. End Sub
  815.  
  816. Private Sub mnuLogFile_Click()
  817.     cmdLogFile_Click
  818. End Sub
  819.  
  820. Private Sub mnuPoint_Click()
  821.     cmdPoint_Click
  822. End Sub
  823.  
  824. Private Sub mnuRefresh_Click()
  825.     cmdRefresh_Click
  826. End Sub
  827.  
  828. Private Sub mnuSave_Click()
  829.     cmdSave_Click
  830. End Sub
  831.  
  832. #If Win32 = 0 Then
  833. Private Sub bstMenu_Message(MsgVal As Integer, wParam As Integer, _
  834.                             lParam As Long, ReturnVal As Long)
  835.     If MsgVal = WM_COMMAND Then
  836.         ReturnVal = SendMessage(hTopWndCur, MsgVal, ByVal wParam, ByVal lParam)
  837.     ElseIf MsgVal = WM_INITMENU Then
  838.         SyncMenu hResourceCur, GetMenu(hTopWndCur)
  839.         ReturnVal = 0&
  840.     End If
  841. End Sub
  842. #End If
  843.  
  844. Private Sub lstResource_Click()
  845.     Dim sType As String, sName As String, i As Integer
  846.  
  847.     sType = lstResource.Text
  848.     BugAssert sType <> sEmpty
  849.     ' Extract resource ID and type
  850.     If Left$(sType, 1) = "0" Then
  851.         ' Append # so Windows will recognize numbers as strings
  852.         sName = "#" & Left$(sType, 5)
  853.         sType = Trim$(Mid$(sType, 7))
  854.     Else
  855.         i = InStr(sType, " ")
  856.         sName = Trim$(Left$(sType, i - 1))
  857.         sType = Trim$(Mid$(sType, i + 1))
  858.     End If
  859.     
  860.     ' Clear last resource and handle new one
  861.     ClearResource
  862.     pbResource.AutoRedraw = False
  863.     If UCase$(sType) <> "BITMAP" Then
  864.         BmpTile pbResource, imgCloud.Picture
  865.     End If
  866.     
  867.     Select Case UCase$(sType)
  868.     Case "CURSOR"
  869.         ShowCursor hModCur, sName
  870.     Case "GROUP_CURSOR", "GROUP CURSOR"
  871.         ShowCursors hModCur, sName
  872.     Case "BITMAP"
  873.         ShowBitmap hModCur, sName
  874.     Case "ICON"
  875.         ShowIcon hModCur, sName
  876.     Case "GROUP_ICON", "GROUP ICON"
  877.         ShowIcons hModCur, sName
  878.     Case "MENU"
  879.         ShowMenu hModCur, sName
  880.     Case "STRING", "STRINGTABLE"
  881.         ShowString hModCur, sName
  882.     Case "WAVE"
  883.         PlayWave hModCur, sName
  884.     Case "AVI"
  885.         PlayAvi hModCur, sName
  886.     Case "FONTDIR", "FONT", "DIALOG", "ACCELERATOR"
  887.         pbResource.Print sType & " selected"
  888.     Case "VERSION"
  889.         pbResource.Print GetVersionData(sModCur, 26)
  890.     Case Else
  891.         ShowData hModCur, sName, sType
  892.     End Select
  893.     pbResource.AutoRedraw = True
  894. End Sub
  895.  
  896. Private Sub UpdateResources(ByVal hMod As Long)
  897.     ' Turn on hourglass, turn off redrawing
  898.     HourGlass Me
  899.     Call LockWindowUpdate(lstResource.hWnd)
  900.     lstResource.Clear
  901.     
  902.     Call EnumResourceTypes(hMod, AddressOf ResTypeProc, Me)
  903.     
  904.     Call LockWindowUpdate(hNull)
  905.     HourGlass Me
  906. End Sub
  907.  
  908. Sub SaveIcon(pb As PictureBox, sName As String)
  909. #If 0 Then
  910.     Static cbIconBits As Integer
  911.  
  912.     ' Set byte size of an icon only one time
  913.     If cbIconBits = 0 Then
  914.         Dim hWnd As Long, hDC As Long
  915.         hWnd = GetDesktopWindow()
  916.         hDC = GetDC(hWnd)
  917.         If GetDeviceCaps(hDC, BITSPIXEL) = 8 Then
  918.             cbIconBits = 1024
  919.         Else
  920.             cbIconBits = 512
  921.         End If
  922.         Call ReleaseDC(hWnd, hDC)
  923.     End If
  924.  
  925.     ' Lock dummy icon so that we can write bits to it
  926.     Dim pIcon As Long
  927.     'pbTemp.Picture = pbBlank.Picture
  928.     pIcon = GlobalLock(pbTemp.Picture)
  929.  
  930.     ' Copy bits from picture to icon dummy, skipping icon header
  931.     Dim iBits As Long, cHeader   As Integer, cColors As Integer
  932.     cHeader = 12
  933.     cColors = 128
  934.     iBits = GetBitmapBits(pb.Image, cbIconBits, pIcon + cHeader + cColors)
  935.     pb.Refresh
  936.     
  937.     ' Unlock icon dummy
  938.     Call GlobalUnlock(pbTemp.Picture)
  939.  
  940.     ' Save icon
  941.     SavePicture pbTemp.Picture, sName
  942. #End If
  943. End Sub
  944.  
  945. Private Sub ClearResource()
  946.     With pbResource
  947.  
  948.     Select Case ordResourceLast
  949.     Case RT_MENU
  950.         Call SetMenu(Me.hWnd, hResourceLast)
  951.         Call DestroyMenu(hResourceCur)
  952.  
  953.     Case RT_GROUP_CURSOR, RT_CURSOR
  954.         MousePointer = ordPointerLast
  955.  
  956.     Case RT_BITMAP
  957.         
  958.     Case RT_GROUP_ICON, RT_ICON, RT_STRING, RT_RCDATA
  959.         ' No restore needed
  960.         
  961.     End Select
  962.     
  963.     .CurrentX = 0
  964.     .CurrentY = 0
  965.     ordResourceLast = 0
  966.     hResourceCur = hNull
  967.     hResourceLast = hNull
  968. '    .Picture = LoadPicture()
  969.     
  970. End With
  971. End Sub
  972.  
  973. Sub ShowBitmap(ByVal hMod As Long, sBitmap As String)
  974. With pbResource
  975.     
  976.     Dim hPal As Long, hPal2 As Long
  977.     ' Convert resource into bitmap handle
  978.     hResourceCur = LoadBitmapPalette(hMod, sBitmap, hPal)
  979.     If hResourceCur = hNull Then
  980.         pbResource.Print "Can't load bitmap: " & sCrLf & sCrLf & _
  981.                          WordWrap(ApiError(Err.LastDllError), 25)
  982.         Exit Sub
  983.     End If
  984.     ' Convert hBitmap to Picture (clip anything larger than picture box)
  985.     .Picture = BitmapToPicture(hResourceCur, hPal)
  986.     ' Set the form palette to use this picture's palette
  987.     Palette = .Picture
  988.     ' Make sure palette is realized
  989.     Refresh
  990.     DoEvents
  991.     ' Draw the palette
  992.     DrawPalette pbResource, hPal, .Width, .Height * 0.1, 0, .Height * 0.9
  993.     ' Record the type for cleanup
  994.     ordResourceLast = RT_BITMAP
  995. End With
  996. End Sub
  997.  
  998. Sub ShowCursor(ByVal hMod As Long, sCursor As String)
  999.     ' Get cursor handle
  1000.     hResourceCur = LoadImage(hMod, sCursor, IMAGE_CURSOR, 0, 0, 0)
  1001.     If hResourceCur <> hNull Then
  1002.         ordPointerLast = MousePointer
  1003.         MousePointer = vbCustom
  1004.         MouseIcon = CursorToPicture(hResourceCur)
  1005.         ordResourceLast = RT_CURSOR
  1006.         Call DrawIconEx(pbResource.hDC, 0, 0, hResourceCur, _
  1007.                         0, 0, 0, hNull, DI_NORMAL)
  1008.     Else
  1009.         pbResource.Print "Can't display cursor: " & sCrLf & sCrLf & _
  1010.                          WordWrap(ApiError(Err.LastDllError), 25)
  1011.     End If
  1012. End Sub
  1013.  
  1014. Sub ShowCursors(ByVal hMod As Long, sCursor As String)
  1015.     BugAssert (hMod <> hNull) And (sCursor <> sEmpty)
  1016.     
  1017.     ' Find the resource
  1018.     Dim hRes As Long, hmemRes As Long, cRes As Long, pRes As Long
  1019.     Dim abGroup() As Byte, abEntry() As Byte
  1020.     hRes = FindResourceStrId(hMod, sCursor, RT_GROUP_CURSOR)
  1021.     If hRes = hNull Then
  1022.         pbResource.Print "Can't display data: " & sCrLf & sCrLf & _
  1023.                          WordWrap(ApiError(Err.LastDllError), 25)
  1024.         Exit Sub
  1025.     End If
  1026.     pbResource.ScaleMode = vbPixels
  1027.     ' Allocate memory block, get size, get pointer, and allocate array
  1028.     hmemRes = LoadResource(hMod, hRes)
  1029.     cRes = SizeofResource(hMod, hRes)
  1030.     pRes = LockResource(hmemRes)
  1031.     ReDim abGroup(cRes)
  1032.     ' Copy memory block to bytes and free
  1033.     CopyMemory abGroup(0), ByVal pRes, cRes
  1034.     Call FreeResource(hmemRes)
  1035.     
  1036.     Dim cImage As Integer, i As Integer, iImage As Integer
  1037.     Dim dxCursor As Integer, dyCursor As Integer, hCursor As Long, s As String
  1038.     ' Validate entry
  1039.     BugAssert BytesToWord(abGroup, wType) = vbResCursor
  1040.     ' Get image count
  1041.     cImage = BytesToWord(abGroup, wCount)
  1042.     ' Set up first entry
  1043.     iImage = entFirst
  1044.     pbResource.CurrentX = 75
  1045.     pbResource.CurrentY = 0
  1046.     For i = 0 To cImage - 1
  1047.         ' Get size and colors
  1048.         dxCursor = abGroup(iImage + wWidth)
  1049.         dyCursor = abGroup(iImage + wHeight)
  1050.         ' For reasons unknown height always comes out twice real size,
  1051.         ' so since all cursors I've seen are square, reuse width as height
  1052.         s = dxCursor & "x" & dxCursor
  1053.         ' Find, load, size, allocate, and copy entry
  1054.         hRes = FindResourceIdId(hMod, BytesToWord(abGroup, iImage + wID), RT_CURSOR)
  1055.         BugAssert hRes
  1056.         hmemRes = LoadResource(hMod, hRes)
  1057.         cRes = SizeofResource(hMod, hRes)
  1058.         pRes = LockResource(hmemRes)
  1059.         ReDim abEntry(cRes)
  1060.         CopyMemory abEntry(0), ByVal pRes, cRes
  1061.         Call FreeResource(hmemRes)
  1062.         ' Create an Cursor from resource data
  1063.         hCursor = CreateIconFromResource(abEntry(0), cRes, False, &H30000)
  1064.         ' Draw Cursor and print description
  1065.         s = s & " (" & BytesToWord(abEntry, 0) & "," & _
  1066.                        BytesToWord(abEntry, 2) & ")"
  1067.         Call DrawIconEx(pbResource.hDC, 0, pbResource.CurrentY, hCursor, _
  1068.                         dxCursor, dxCursor, 0, hNull, DI_NORMAL)
  1069.         pbResource.Print s
  1070.         ' Move to next entry
  1071.         pbResource.CurrentY = pbResource.CurrentY + dxCursor
  1072.         pbResource.CurrentX = 75
  1073.         iImage = iImage + cEntrySize
  1074.     Next
  1075.     pbResource.ScaleMode = vbTwips
  1076.     ' Use the best cursor
  1077.     hResourceCur = LoadImage(hMod, sCursor, IMAGE_CURSOR, 0, 0, 0)
  1078.     BugAssert hResourceCur <> hNull
  1079.     ordPointerLast = MousePointer
  1080.     MousePointer = vbCustom
  1081.     MouseIcon = IconToPicture(hResourceCur)
  1082.     ordResourceLast = RT_CURSOR
  1083.     
  1084. End Sub
  1085.  
  1086. Sub ShowData(ByVal hMod As Long, sData As String, _
  1087.              Optional sDataType As String = "RCDATA")
  1088.     
  1089.     Dim hRes As Long, hmemRes As Long, cRes As Long
  1090.     Dim pRes As Long, abRes() As Byte
  1091.     If sDataType = "RCDATA" Then
  1092.         hRes = FindResourceStrId(hMod, sData, RT_RCDATA)
  1093.     Else
  1094.         hRes = FindResourceStrStr(hMod, sData, sDataType)
  1095.     End If
  1096.     If hRes = hNull Then
  1097.         pbResource.Print "Can't display data: " & sCrLf & sCrLf & _
  1098.                          WordWrap(ApiError(Err.LastDllError), 25)
  1099.         Exit Sub
  1100.     End If
  1101.     ' Allocate memory block and get its size
  1102.     hmemRes = LoadResource(hMod, hRes)
  1103.     cRes = SizeofResource(hMod, hRes)
  1104.     ' Don't dump more than 500 bytes
  1105.     If cRes > 500 Then cRes = 500
  1106.     ' Lock it to get pointer
  1107.     pRes = LockResource(hmemRes)
  1108.     ' Allocate byte array of right size
  1109.     ReDim abRes(cRes)
  1110.     ' Copy memory block to array
  1111.     CopyMemory abRes(0), ByVal pRes, cRes
  1112.     ' Free resource (no need to unlock)
  1113.     Call FreeResource(hmemRes)
  1114.     pbResource.Print HexDump(abRes, False)
  1115.  
  1116. End Sub
  1117.  
  1118. Sub ShowIcon(ByVal hMod As Long, sIcon As String)
  1119.     BugAssert (hMod <> hNull) And (sIcon <> sEmpty)
  1120.     
  1121.     ' Load icon resource
  1122.     hResourceCur = LoadImage(hMod, sIcon, IMAGE_ICON, 0, 0, 0)
  1123.     With pbResource
  1124.         If hResourceCur <> hNull Then
  1125.             ' Convert icon handle to Picture
  1126.             Dim pic As New StdPicture
  1127.             Set pic = IconToPicture(hResourceCur)
  1128.             pbResource.PaintPicture pic, 0, 0
  1129.             ordResourceLast = RT_ICON
  1130.         Else
  1131.             pbResource.Print "Can't display icon: " & sCrLf & sCrLf & _
  1132.                              WordWrap(ApiError(Err.LastDllError), 25)
  1133.         End If
  1134.     End With
  1135.  
  1136. End Sub
  1137.  
  1138. Sub ShowIcons(ByVal hMod As Long, sIcon As String)
  1139.     BugAssert (hMod <> hNull) And (sIcon <> sEmpty)
  1140.     
  1141.     ' Find the resource
  1142.     Dim hRes As Long, hmemRes As Long, cRes As Long, pRes As Long
  1143.     Dim abGroup() As Byte, abEntry() As Byte
  1144.     hRes = FindResourceStrId(hMod, sIcon, RT_GROUP_ICON)
  1145.     If hRes = hNull Then
  1146.         pbResource.Print "Can't display data: " & sCrLf & sCrLf & _
  1147.                          WordWrap(ApiError(Err.LastDllError), 25)
  1148.         Exit Sub
  1149.     End If
  1150.     pbResource.ScaleMode = vbPixels
  1151.     ' Allocate memory block, get size, get pointer, and allocate array
  1152.     hmemRes = LoadResource(hMod, hRes)
  1153.     cRes = SizeofResource(hMod, hRes)
  1154.     pRes = LockResource(hmemRes)
  1155.     ReDim abGroup(cRes)
  1156.     ' Copy memory block to bytes and free
  1157.     CopyMemory abGroup(0), ByVal pRes, cRes
  1158.     Call FreeResource(hmemRes)
  1159.     
  1160.     Dim cImage As Integer, i As Integer, iImage As Integer
  1161.     Dim dxIcon As Byte, dyIcon As Byte, hIcon As Long, s As String
  1162.     ' Validate entry
  1163.     BugAssert BytesToWord(abGroup, wType) = vbResIcon
  1164.     ' Get image count
  1165.     cImage = BytesToWord(abGroup, wCount)
  1166.     ' Set up first entry
  1167.     iImage = entFirst
  1168.     pbResource.CurrentX = 75
  1169.     pbResource.CurrentY = 0
  1170.     For i = 0 To cImage - 1
  1171.         ' Get size and colors
  1172.         dxIcon = abGroup(iImage + bWidth)
  1173.         dyIcon = abGroup(iImage + bHeight)
  1174.         s = dxIcon & "x" & dyIcon & ", " & _
  1175.             abGroup(iImage + bColorCount) & " color"
  1176.         ' Find, load, size, allocate, and copy entry
  1177.         hRes = FindResourceIdId(hMod, _
  1178.                                 BytesToWord(abGroup, iImage + wID), _
  1179.                                 RT_ICON)
  1180.         BugAssert hRes
  1181.         hmemRes = LoadResource(hMod, hRes)
  1182.         cRes = SizeofResource(hMod, hRes)
  1183.         pRes = LockResource(hmemRes)
  1184.         ReDim abEntry(cRes)
  1185.         CopyMemory abEntry(0), ByVal pRes, cRes
  1186.         Call FreeResource(hmemRes)
  1187.         ' Create an icon from resource data
  1188.         hIcon = CreateIconFromResource(abEntry(0), cRes, True, &H30000)
  1189.         ' Draw icon and print description
  1190.         Call DrawIconEx(pbResource.hDC, 0, pbResource.CurrentY, hIcon, _
  1191.                         dxIcon, dyIcon, 0, hNull, DI_NORMAL)
  1192.         pbResource.Print s
  1193.         ' Move to next entry
  1194.         pbResource.CurrentY = pbResource.CurrentY + dyIcon
  1195.         pbResource.CurrentX = 75
  1196.         iImage = iImage + cEntrySize
  1197.     Next
  1198.     pbResource.ScaleMode = vbTwips
  1199.     hResourceCur = hIcon
  1200.     ordResourceLast = RT_ICON
  1201.     
  1202. End Sub
  1203.  
  1204. Sub ShowString(ByVal hMod As Long, sString As String)
  1205.     Dim hRes As Long, hmemRes As Long, cRes As Long
  1206.     Dim pRes As Long, abRes() As Byte, i As Long
  1207.     hRes = FindResourceStrId(hMod, sString, RT_STRING)
  1208.     If hRes = hNull Then
  1209.         pbResource.Print "Can't display string: " & sCrLf & sCrLf & _
  1210.                          WordWrap(ApiError(Err.LastDllError), 25)
  1211.         Exit Sub
  1212.     End If
  1213.     ' Allocate memory block and get its size
  1214.     hmemRes = LoadResource(hMod, hRes)
  1215.     cRes = SizeofResource(hMod, hRes)
  1216.     ' Don't dump more than 500 bytes
  1217.     If cRes > 500 Then cRes = 500
  1218.     ' Lock it to get pointer
  1219.     pRes = LockResource(hmemRes)
  1220.     ' Allocate byte array of right size
  1221.     ReDim abRes(cRes)
  1222.     ' Copy memory block to array
  1223.     CopyMemory abRes(0), ByVal pRes, cRes
  1224.     ' Free resource (no need to unlock)
  1225.     Call FreeResource(hmemRes)
  1226.     pbResource.Print HexDump(abRes, False)
  1227. End Sub
  1228.  
  1229. Sub ShowMenu(ByVal hMod As Long, sMenu As String)
  1230.  
  1231.     hResourceCur = LoadMenu(hMod, sMenu)
  1232.     If hResourceCur <> 0 Then
  1233.         pbResource.Print "Menu set to: "
  1234.         pbResource.Print lstTopWin.Text
  1235.         hResourceLast = GetMenu(Me.hWnd)
  1236.         Call SetMenu(Me.hWnd, hResourceCur)
  1237.         ordResourceLast = RT_MENU
  1238.     Else
  1239.         pbResource.Print "Can't display menu: " & sCrLf & sCrLf & _
  1240.                          WordWrap(ApiError(Err.LastDllError), 25)
  1241.     End If
  1242. End Sub
  1243.  
  1244. Sub PlayWave(ByVal hMod As Long, sWave As String)
  1245.     ' Convert wave resource to memory
  1246.     Dim hWave As Long, hmemWave As Long, pWave As Long
  1247.     hWave = FindResourceStrStr(hMod, sWave, "WAVE")
  1248.     hmemWave = LoadResource(hMod, hWave)
  1249.     pWave = LockResource(hmemWave)
  1250.     Call FreeResource(hmemWave)
  1251.     ' Play it
  1252.     If sndPlaySoundAsLp(pWave, SND_MEMORY Or SND_NODEFAULT) Then
  1253.         pbResource.Print "Sound played"
  1254.     Else
  1255.         pbResource.Print "Can't play sound: " & sCrLf & sCrLf & _
  1256.                          WordWrap(ApiError(Err.LastDllError), 25)
  1257.     End If
  1258. End Sub
  1259.  
  1260. Sub PlayAvi(ByVal hMod As Long, sWave As String)
  1261.     Dim hWave As Long, hmemWave As Long, pWave As Long
  1262.     hWave = FindResourceStrStr(hMod, sWave, "WAVE")
  1263.     hmemWave = LoadResource(hMod, hWave)
  1264.     pWave = LockResource(hmemWave)
  1265.     ' Play AVI from memory
  1266.     Call UnlockResource(hmemWave)
  1267.     Call FreeResource(hmemWave)
  1268. End Sub
  1269.  
  1270. Function GetVersionData(sExe As String, _
  1271.                         Optional ByVal cMaxChar As Long = 40) As String
  1272.     Dim version As New CVersion, s As String
  1273.     On Error GoTo NoVersionData
  1274. With version
  1275.     ' Initialize version object
  1276.     version = sExe
  1277.     ' Read and return properties
  1278.     s = s & WordWrap(.ProductName, cMaxChar) & sCrLf
  1279.     s = s & "Exe type: " & .ExeType & sCrLf
  1280.     s = s & "Internal name: " & .InternalName & sCrLf
  1281.     If .BuildString <> sEmpty Then
  1282.         s = s & "Build: " & .BuildString & sCrLf
  1283.     End If
  1284.     If .OriginalFilename <> sEmpty And _
  1285.        .OriginalFilename <> .InternalName Then
  1286.         s = s & "Original name: " & .OriginalFilename & sCrLf
  1287.     End If
  1288.     s = s & "Product version: " & .FullProductVersion & sCrLf
  1289.     s = s & "File version: " & .FullFileVersion & sCrLf
  1290.     s = s & "Company: " & WordWrap(.Company, cMaxChar) & sCrLf
  1291.     If .Comments <> sEmpty Then
  1292.         s = s & "Comments: " & WordWrap(.Comments, cMaxChar) & sCrLf
  1293.     End If
  1294.     s = s & "Copyright: " & WordWrap(.Copyright, cMaxChar) & sCrLf
  1295.     If .Trademarks <> sEmpty Then
  1296.         s = s & "Trademarks: " & WordWrap(.Trademarks, cMaxChar) & sCrLf
  1297.     End If
  1298.     's = s & "Host OS: " & .Environment & sCrLf
  1299.     s = s & "OS Version: " & .ProductVersionString & sCrLf
  1300.     If .Description <> sEmpty Then
  1301.         s = s & "Description: " & WordWrap(.Description, cMaxChar) & sCrLf
  1302.     End If
  1303.     Dim dt As Date
  1304.     dt = .TimeStamp
  1305.     If dt <> 0 Then
  1306.         s = s & "Time stamp: " & dt & sCrLf
  1307.     End If
  1308.     GetVersionData = s
  1309. End With
  1310.     Exit Function
  1311.     
  1312. NoVersionData:
  1313.     GetVersionData = "Unable to display version information"
  1314. End Function
  1315.  
  1316. Sub UpdateDisplay(eut As EUpdateType, hThing As Long)
  1317.     Dim idProc As Long, hWnd As Long, hTopWnd As Long, hMod As Long
  1318.     
  1319.     ' If top window is no longer valid, start from scratch
  1320.     Dim hTemp As Long
  1321.     If eut = eutTopWindow Or eut = eutWindow Then
  1322.         hTemp = ProcIDFromWnd(hThing)
  1323.     Else
  1324.         hTemp = ProcIDFromWnd(hWndCur)
  1325.     End If
  1326.     If hTemp = 0 Then
  1327.         RefreshAllLists
  1328.         Exit Sub
  1329.     End If
  1330.  
  1331.     Select Case eut
  1332.     Case eutTopWindow
  1333.         BugMessage "Top window update"
  1334.         idProc = ProcIDFromWnd(hThing)
  1335.         hWnd = hThing
  1336.         hTopWnd = hThing
  1337.         hMod = hModCur
  1338.     Case eutWindow
  1339.         BugMessage "Window update"
  1340.         idProc = ProcIDFromWnd(hThing)
  1341.         hWnd = hThing
  1342.         hTopWnd = TopWndFromProcID(idProc)
  1343.         hMod = hModCur
  1344.     Case eutProcess
  1345.         BugMessage "Process update"
  1346.         idProc = hThing
  1347.         hWnd = TopWndFromProcID(idProc)
  1348.         ' If process doesn't belong to a window in the
  1349.         ' top window list, don't change top window or
  1350.         ' window hierarchy displays
  1351.         If hWnd = hNull Then
  1352.             hWnd = hWndCur
  1353.             hTopWnd = hTopWndCur
  1354.         Else
  1355.             hTopWnd = hWnd
  1356.         End If
  1357.         hMod = hModCur
  1358.     Case eutModule
  1359.         BugMessage "Module update"
  1360.         hWnd = hWndCur
  1361.         hTopWnd = hTopWndCur
  1362.         idProc = idProcCur
  1363.         hMod = hThing
  1364.         sModCur = lstModule.Text
  1365.     End Select
  1366.     
  1367.     If hWnd Then BugMessage ExeNameFromWnd(hWnd)
  1368.     
  1369.     ' If window changed, update it
  1370.     If hWnd <> hWndCur Then
  1371.         hWndCur = hWnd
  1372.         lblWin.Caption = GetWndInfo(hWnd)
  1373.         tvwWin.Nodes.Item("W" & hWnd).Selected = True
  1374.     End If
  1375.     
  1376.     ' If top window changed, update it
  1377.     If hTopWnd <> hTopWndCur Then
  1378.         hTopWndCur = hTopWnd
  1379.         lstTopWin.ListIndex = LookupItemData(lstTopWin, hTopWnd)
  1380.     End If
  1381.     
  1382.     ' If process changed, update it
  1383.     If idProc <> idProcCur Then
  1384.         idProcCur = idProc
  1385.         ' Unload previous process
  1386.         If hModFree Then Call FreeLibrary(hModFree)
  1387.         sModCur = ExePathFromProcID(idProcCur)
  1388.         hMod = LoadLibraryEx(sModCur, 0, LOAD_LIBRARY_AS_DATAFILE)
  1389.         ' Save process handle for FreeLibrary
  1390.         hModFree = hMod
  1391.         ' Store module handles of new process
  1392.         RefreshModuleList idProc
  1393.         lblProc.Caption = GetProcInfo(idProc)
  1394.         lstProcess.ListIndex = LookupItemData(lstProcess, idProc)
  1395.     End If
  1396.         
  1397.     ' Update resources if module changed
  1398.     If hMod <> hModCur Then
  1399.         ' Update the resource list and the module information
  1400.         hModCur = hMod
  1401.         UpdateResources hModCur
  1402.         lblMod.Caption = "Module: " & sModCur & sCrLf & _
  1403.                          "Handle: " & Hex$(hMod)
  1404.         If lstResource.ListCount Then lstResource.ListIndex = 0
  1405.     End If
  1406.     
  1407.     If hWndCur Then hInstCur = InstFromWnd(hWndCur)
  1408.     
  1409. End Sub
  1410.  
  1411. Private Sub tvwWin_NodeClick(ByVal Node As ComctlLib.Node)
  1412.     ' Get current window handle from treeview node Key property
  1413.     fInClick = True
  1414.     UpdateDisplay eutWindow, CLng(Mid$(tvwWin.SelectedItem.Key, 2))
  1415.     fInClick = False
  1416. End Sub
  1417.